home *** CD-ROM | disk | FTP | other *** search
/ The Utilities Experience / The Utilities Experience - Volume 1.iso / software / misc / o-z / x-windows / mesa-amiwin / src / amesa.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-12  |  19.8 KB  |  918 lines

  1. /* amesa.c */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  1.2
  6.  * Copyright (C) 1995  Brian Paul  (brianp@ssec.wisc.edu)
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * Amiga/Mesa interface.
  26.  */
  27.  
  28.  
  29. /*
  30. $Id: amesa.c,v 1.5 1995/06/12 15:36:31 brianp Exp $
  31.  
  32. $Log: amesa.c,v $
  33.  * Revision 1.5  1995/06/12  15:36:31  brianp
  34.  * changed color arrays to GLubyte
  35.  * use 8.3 filenames
  36.  *
  37.  * Revision 1.4  1995/05/31  19:33:50  brianp
  38.  * removed references to MAX_VERTICES
  39.  *
  40.  * Revision 1.3  1995/05/22  21:02:41  brianp
  41.  * Release 1.2
  42.  *
  43.  * Revision 1.2  1995/03/04  19:29:44  brianp
  44.  * 1.1 beta revision
  45.  *
  46.  * Revision 1.1  1995/02/24  14:15:49  brianp
  47.  * Initial revision
  48.  *
  49.  */
  50.  
  51.  
  52. /* TODO: THIS INTERFACE PROBABLY DOESN'T WORK AS IT IS VERY OUT OF DATE */
  53.  
  54.  
  55. #include <stdio.h>
  56. #include <stdlib.h>
  57. #include <string.h>
  58. #include <graphics/rastport.h>
  59. #include <hardware/blit.h>
  60. #include <clib/graphics_protos.h>
  61. #include "bresenhm.h"
  62. #include "context.h"
  63. #include "dd.h"
  64. #include "GL/amesa.h"
  65. #include "polygons.h"
  66. #include "xform.h"
  67.  
  68.  
  69. #define MAX_POLYGON 300
  70.  
  71.  
  72. struct amesa_context {
  73.         struct gl_context *gl_ctx;    /* the main library context */
  74.  
  75.     GLboolean rgb_flag;    /* IF rgb_flag==GL_TRUE THEN
  76.                     window is on a HAM screen
  77.                     front_rp points to window's rastport
  78.                     back_rp is NULL
  79.                     rp == front_rp
  80.                     rgb_buffer is the back buffer
  81.                     pixel = current packed RGBA value
  82.                    ELSE
  83.                     window is on a regular, CI screen
  84.                     front_rp points to window's rastport
  85.                     back_rp points to back buffer or NULL
  86.                     rp = front_rp or back_rp
  87.                     rgb_buffer = NULL
  88.                     pixel = current color index
  89.                    ENDIF
  90.                 */
  91.  
  92.     GLboolean db_flag;        /* double buffering flag */
  93.  
  94.     struct Window *window;        /* the Intuition window */
  95.         struct RastPort *front_rp;    /* front rastport */
  96.         struct RastPort *back_rp;    /* back rastport (NULL if SB or RGB) */
  97.     struct RastPort *rp;        /* current rastport */
  98.  
  99.     GLenum drawbuffer;
  100.     GLenum readbuffer;
  101.  
  102.     GLuint width, height;        /* drawable area */
  103.     GLuint depth;            /* bits per pixel */
  104.  
  105.     GLuint pixel;            /* current color index or RGBA value */
  106.     GLuint *rgb_buffer;        /* back buffer when in RGBA mode */
  107.  
  108.     GLint left, bottom;        /* offsets due to window border */
  109. };
  110.  
  111.  
  112.  
  113. static AMesaContext Current = NULL;
  114.  
  115.  
  116. /*
  117.  *
  118.  * Private functions
  119.  *
  120.  */
  121.  
  122.  
  123. /*
  124.  * Create a new rastport to use as a back buffer.
  125.  * Input:  width, height - size in pixels
  126.  *         depth - number of bitplanes
  127.  */
  128. static struct RastPort *make_rastport( int width, int height, int depth )
  129. {
  130.    struct RastPort *rp;
  131.    struct BitMap *bm;
  132.    int i;
  133.  
  134.    /* add error checking! */
  135.    bm = (struct BitMap *) malloc( sizeof(struct BitMap) );
  136.    InitBitMap( bm, depth, width, height );
  137.    for (i=0;i<depth;i++) {
  138.       bm->Planes[i] = AllocRaster( width, height );
  139.    }
  140.    rp = (struct RastPort *) malloc( sizeof(struct RastPort) );
  141.    InitRastPort( rp );
  142.    rp->BitMap = bm;
  143.  
  144.    return rp;
  145.  
  146. }
  147.  
  148.  
  149. /*
  150.  * Deallocate a rastport.
  151.  */
  152. static void destroy_rastport( struct RastPort *rp )
  153. {
  154.    int i, depth;
  155.  
  156.    if (rp) {
  157.       depth = rp->BitMap->Depth;
  158.       for (i=0;i<depth;i++) {
  159.          FreeRaster( rp->BitMap->Planes[i], 
  160.               rp->BitMap->BytesPerRow*8,
  161.              rp->BitMap->Rows );
  162.       }
  163.       free( rp->BitMap );
  164.       free( rp );
  165.    }
  166. }
  167.  
  168.  
  169.  
  170. /*
  171.  * Construct a temporary raster for use by the given rasterport.
  172.  * Temp rasters are used for polygon drawing.
  173.  */
  174. static void make_temp_raster( struct RastPort *rp )
  175. {
  176.    unsigned long width, height;
  177.    PLANEPTR p;
  178.    struct TmpRas *tmpras;
  179.    struct AreaInfo *areainfo;
  180.    UWORD *pattern;
  181.    APTR vbuffer;
  182.  
  183.    width = rp->BitMap->BytesPerRow*8;
  184.    height = rp->BitMap->Rows;
  185.  
  186.    /* allocate structures */
  187.    p = AllocRaster( width, height );
  188.    tmpras = (struct TmpRas *) malloc( sizeof(struct TmpRas) );
  189.    areainfo = (struct AreaInfo *) malloc( sizeof(struct AreaInfo) );
  190.    pattern = (UWORD *) malloc( sizeof(UWORD) );
  191.    *pattern = 0xffffffff;
  192.    vbuffer = (APTR) malloc( MAX_POLYGON * 5 * sizeof(WORD) );
  193.  
  194.    /* initialize */
  195.    InitTmpRas( tmpras, p, ((width+15)/16)*height );
  196.    InitArea( areainfo, vbuffer, MAX_POLYGON );
  197.  
  198.    /* bind to rastport */
  199.    rp->AreaPtrn = pattern;
  200.    rp->TmpRas = tmpras;
  201.    rp->AreaInfo = areainfo;
  202.    rp->AreaPtSz = 0;
  203. }
  204.  
  205.  
  206.  
  207.  
  208. /*
  209.  * Destroy a temp raster.
  210.  */
  211. static void destroy_temp_raster( struct RastPort *rp )
  212. {
  213.    /* bitmap */
  214.    if (rp->TmpRas) {
  215.       FreeRaster( rp->TmpRas->RasPtr,
  216.           rp->BitMap->BytesPerRow*8,
  217.           rp->BitMap->Rows );
  218.       free( rp->TmpRas );
  219.       rp->TmpRas = NULL;
  220.    }
  221.  
  222.    if (rp->AreaInfo) {
  223.       free( rp->AreaInfo->VctrTbl );
  224.       free( rp->AreaInfo );
  225.       rp->AreaInfo = NULL;
  226.    }
  227.  
  228.    if (rp->AreaPtrn) {
  229.       free( rp->AreaPtrn );
  230.       rp->AreaPtrn = NULL;
  231.    }
  232. }
  233.  
  234.  
  235.  
  236. /*
  237.  * Write a pixel to a bitmap which is in HAM mode.
  238.  */
  239. static void ham_plot( struct BitMap *bm, int x, int y, int pixel )
  240. {
  241.    int p, pmask;
  242.    int offset;
  243.    unsigned char *ptr, mask, bit;
  244.  
  245.    offset = y * (int) bm->BytesPerRow + (x >> 3);
  246.    bit = 128 >> (x & 7);
  247.    mask = 0xff ^ bit;
  248.  
  249.    pmask = 1;
  250.    for (p=0;p<6;p++) {
  251.       ptr = bm->Planes[p] + offset;
  252.       if (pixel & pmask) {
  253.      /* set bit */
  254.      *ptr = *ptr | bit;
  255.       }
  256.       else {
  257.      /* clear bit */
  258.      *ptr = *ptr & mask;
  259.       }
  260.       pmask = pmask << 1;
  261.    }
  262. }
  263.  
  264.  
  265. /*
  266.  * Write a row of pixels to a 6-plane bitmap.
  267.  */
  268. static void ham_row( struct BitMap *bm, int y, unsigned char pixel[] )
  269. {
  270.    int byte, nbytes, i, offset;
  271.  
  272.    nbytes = bm->BytesPerRow;
  273.    offset = y * nbytes;
  274.    i = 0;
  275.  
  276.    for (byte=0;byte<nbytes;byte++) {
  277.       register UBYTE bitmask;
  278.       UBYTE pixcache0, pixcache1, pixcache2, pixcache3, pixcache4, pixcache5;
  279.  
  280.       pixcache0 = pixcache1 = pixcache2 = 0;
  281.       pixcache3 = pixcache4 = pixcache5 = 0;
  282.  
  283.       for (bitmask=128; bitmask; bitmask = bitmask >> 1) {
  284.      register UBYTE pixel_i = pixel[i];
  285.  
  286.      if (pixel_i &  1) pixcache0 |= bitmask;
  287.      if (pixel_i &  2) pixcache1 |= bitmask;
  288.      if (pixel_i &  4) pixcache2 |= bitmask;
  289.      if (pixel_i &  8) pixcache3 |= bitmask;
  290.      if (pixel_i & 16) pixcache4 |= bitmask;
  291.      if (pixel_i & 32) pixcache5 |= bitmask;
  292.  
  293.      i++;
  294.       }
  295.  
  296.       bm->Planes[0][offset] = pixcache0;
  297.       bm->Planes[1][offset] = pixcache1;
  298.       bm->Planes[2][offset] = pixcache2;
  299.       bm->Planes[3][offset] = pixcache3;
  300.       bm->Planes[4][offset] = pixcache4;
  301.       bm->Planes[5][offset] = pixcache5;
  302.  
  303.       offset++;
  304.    }
  305.  
  306. }
  307.  
  308.  
  309.  
  310. /*
  311.  * Convert and copy pixels from 32-bit RGBA format to 6-bit HAM.
  312.  * Input:  width, height - size of buffer
  313.  *         rgba - pointer to width*height 32-bit RGBA pixels
  314.  *         hamrp - HAM mode rasterport
  315.  */
  316. static void rgba_to_ham( GLuint width, GLuint height,
  317.              GLuint *rgba,
  318.              struct RastPort *hamrp )
  319. {
  320.    GLuint x, y;
  321.    GLint pr, pg, pb;
  322.    GLint pixel, r, g, b;
  323.    GLint dr, dg, db;
  324.    struct BitMap *bm;
  325.    unsigned char pixel_buf[1280];
  326.  
  327. /*   SetRast( hamrp, 0 );*/
  328.  
  329.    bm = hamrp->BitMap;
  330.  
  331.    for (y=0;y<height;y++) {
  332.       pr = pg = pb = 0;
  333.       for (x=0;x<width;x++) {
  334.  
  335.      /* extract 4-bit r, g, b values */
  336.          pixel = rgba[y*width+x];
  337.          r = (pixel & 0x0000f0) >> 4;
  338.      g = (pixel & 0x00f000) >> 12;
  339.          b = (pixel & 0xf00000) >> 20;
  340.  
  341.          dr = r-pr;  if (dr<0) dr = -dr;
  342.      dg = g-pg;  if (dg<0) dg = -dg;
  343.      db = b-pb;  if (db<0) db = -db;
  344.  
  345.      /* modify the component which is most different from prev pixel */
  346.      if (dr>=dg && dr>=db) {
  347.         pr = r;
  348.         pixel_buf[x] = 32+r;
  349.      }
  350.      else if (dg>=dr && dg>=db) {
  351.         pg = g;
  352.         pixel_buf[x] = 48+g;
  353.      }
  354.      else {
  355.         pb = b;
  356.         pixel_buf[x] = 16+b;
  357.      }
  358.  
  359.       }
  360.       ham_row( bm, y, pixel_buf );
  361.    }
  362. }
  363.  
  364.  
  365.  
  366. /*
  367.  * Allocate all auxillary buffers as needed.  This function is used
  368.  * for initial setup and when window resizes occur.
  369.  */
  370. static void alloc_aux_buffers( AMesaContext c )
  371. {
  372.    if (c->rgb_flag) {
  373.       /* color buffer */
  374.  
  375.       if (c->rgb_buffer) {
  376.      free( c->rgb_buffer);
  377.       }
  378.       c->rgb_buffer = (GLuint *)
  379.                     malloc( c->width * c->height * sizeof(GLuint) );
  380.       if (!c->rgb_buffer) {
  381.      /* unable to open true-color buffer */
  382.      printf("Not enough memory for RGB buffer\n");
  383.       }
  384.       c->rp = c->front_rp;
  385.    }
  386.    else {
  387.       /* index buffer */
  388.  
  389.       if (c->db_flag) {
  390.          /* deallocate current back buffer, if any */
  391.      if (c->back_rp) {
  392.         destroy_temp_raster( c->back_rp );
  393.         destroy_rastport( c->back_rp );
  394.      }
  395.      /* allocate new back buffer */
  396.          c->back_rp = make_rastport( c->window->Width, c->window->Height,
  397.                      c->depth );
  398.      if (c->back_rp) {
  399.         make_temp_raster( c->back_rp );
  400.         c->rp = c->back_rp;
  401.      }
  402.      else {
  403.         c->rp = c->front_rp;
  404.      }
  405.       }
  406.       else {
  407.      c->rp = c->front_rp;
  408.       }
  409.    }
  410.  
  411.    /* deallocte front temp raster, if any */
  412.    destroy_temp_raster( c->front_rp);
  413.    /* allocate new front temp raster */
  414.    make_temp_raster( c->front_rp );
  415. }
  416.  
  417.  
  418.  
  419. /*
  420.  *
  421.  * Public functions
  422.  *
  423.  */
  424.  
  425.  
  426.  
  427. /*
  428.  * Given an Intuition window pointer, create a new AMesaContext
  429.  * Notes:  If rgb_flag is true, db_flag must also be true.
  430.  *
  431.  * Input:  window - Intuition window to render into.
  432.  *         db_flag - GL_TRUE = double buffered, GL_FALSE = single buffered
  433.  *         rgb_flag - GL_TRUE = RGB window, GL_FALSE = Color Index window
  434.  * Return:  a AMesaContext or NULL if error.
  435.  */
  436. AMesaContext AMesaCreateContext( struct Window *window,
  437.                  GLboolean db_flag,
  438.                  GLboolean rgb_flag )
  439. {
  440.    AMesaContext c;
  441.  
  442.    /* allocate amesa_struct */
  443.    c = (AMesaContext) malloc( sizeof(struct amesa_context) );
  444.    if (!c) {
  445.       return NULL;
  446.    }
  447.  
  448.    /* initialize the context */
  449.    c->gl_ctx = gl_new_context();
  450.    c->rgb_flag = rgb_flag;
  451.    c->db_flag = db_flag;
  452.    c->window = window;
  453.    c->front_rp = window->RPort;
  454.    c->back_rp = NULL;
  455.    c->rp = NULL;
  456.    c->width = window->Width - window->BorderLeft - window->BorderRight;
  457.    c->height = window->Height - window->BorderTop - window->BorderBottom;
  458.    c->left = window->BorderLeft;
  459.    c->bottom = window->Height - window->BorderBottom - 1;
  460.    c->rgb_buffer = NULL;
  461.  
  462.    if (rgb_flag) {
  463.       /* RGBA color buffers */
  464.       c->gl_ctx->RGBAflag = GL_TRUE;
  465.       c->depth = 32;
  466.       alloc_aux_buffers( c );
  467.       c->pixel = 0;
  468.    }
  469.    else {
  470.       /* CI color buffers */
  471.       c->gl_ctx->RGBAflag = GL_FALSE;
  472.       c->depth = window->RPort->BitMap->Depth;
  473.       alloc_aux_buffers( c );
  474.       c->pixel = 1;
  475.    }
  476.  
  477.    if (db_flag) {
  478.       c->gl_ctx->Color.DrawBuffer = GL_BACK;
  479.    }
  480.    else {
  481.       c->gl_ctx->Color.DrawBuffer = GL_FRONT;
  482.    }
  483.  
  484.  
  485. /*
  486.    printf("win width = %d\n", (int) window->Width );
  487.    printf("win height = %d\n", (int) window->Height );
  488.    printf("left = %d\n", (int) window->BorderLeft );
  489.    printf("rightt = %d\n", (int) window->BorderRight );
  490.    printf("top = %d\n", (int) window->BorderTop );
  491.    printf("bottom = %d\n", (int) window->BorderBottom );
  492. */
  493.  
  494.    c->gl_ctx->BufferWidth = c->width;
  495.    c->gl_ctx->BufferHeight = c->height;
  496.  
  497.    return (AMesaContext) c;
  498. }
  499.  
  500.  
  501.  
  502. void AMesaDestroyContext( AMesaContext c )
  503. {
  504.    gl_destroy_context( c->gl_ctx );
  505.    if (c->rgb_flag) {
  506.       free( c->rgb_buffer );
  507.    }
  508.    else {
  509.       if (c->back_rp) {
  510.          destroy_temp_raster( c->back_rp );
  511.          destroy_rastport( c->back_rp );
  512.       }
  513.    }
  514.    destroy_temp_raster( c->front_rp );
  515.  
  516.    free( (void *) c );
  517. }
  518.  
  519.  
  520.  
  521. int AMesaMakeCurrent( AMesaContext ctx )
  522. {
  523.    AMesaContextc = ctx;
  524.  
  525.    gl_set_context( ctx->gl_ctx );
  526.    Current = ctx;
  527.    if (Current->gl_ctx->Viewport.Width==0) {
  528.       /* initialize viewport to window size */
  529.       gl_viewport( 0, 0, Current->width, Current->height );
  530.    }
  531.  
  532. }
  533.  
  534.  
  535.  
  536. AMesaContext AMesaGetCurrentContext( void )
  537. {
  538.    return Current;
  539. }
  540.  
  541.  
  542.  
  543. void AMesaSwapBuffers( void )
  544. {
  545.    if (Current->rgb_flag) {
  546.       rgba_to_ham( Current->width, Current->height,
  547.            Current->rgb_buffer,
  548.            Current->front_rp );
  549.    }
  550.    else {
  551.       if (Current->back_rp) {
  552.          unsigned long minterm = 0xc0;
  553.      int x = Current->window->BorderLeft;
  554.      int y = Current->window->BorderTop;
  555.          ClipBlit( Current->back_rp, x, y,   /* from */
  556.                Current->front_rp, x, y,  /* to */
  557.            Current->width, Current->height,  /* size */
  558.            minterm );
  559.       }
  560.    }
  561. }
  562.  
  563.  
  564. /*
  565.  *
  566.  * Device driver functions.
  567.  *
  568.  */
  569.  
  570.  
  571.  
  572. /****************************************/
  573. /*           Miscellaneous              */
  574. /****************************************/
  575.  
  576.  
  577. /*
  578.  * Finish any pending rendering operations, then return.
  579.  */
  580. void dd_flush( void )
  581. {
  582.    if (Current->rgb_flag && !Current->db_flag) {
  583.       /* copy RGB buffer to ham window */
  584.       rgba_to_ham( Current->width, Current->height,
  585.            Current->rgb_buffer,
  586.            Current->front_rp );
  587.    }
  588.  
  589. }
  590.  
  591.  
  592.  
  593. /*
  594.  * Return information about current color buffer.
  595.  * Output:  mode - 0 = CI, 1 = RGBA
  596.  *          depth - In Color Index mode, return bits/pixel
  597.  *                - In RGBA mode, return bits/component
  598.  */
  599. void dd_buffer_info( GLuint *width, GLuint *height,
  600.              GLuint *mode, GLuint *depth )
  601. {
  602.    struct Window *w;
  603.    GLint new_width, new_height;
  604.  
  605.    /* get new window dimensions */
  606.    w = Current->window;
  607.    new_width  = w->Width  - w->BorderLeft - w->BorderRight;
  608.    new_height = w->Height - w->BorderTop  - w->BorderBottom;
  609.  
  610.    if (new_width!=Current->width || new_height!=Current->height) {
  611.       Current->width = new_width;
  612.       Current->height = new_height;
  613.       Current->left = w->BorderLeft;
  614.       Current->bottom = w->Height - w->BorderBottom - 1;
  615.       alloc_aux_buffers( Current );
  616.    }
  617.  
  618.    *width = Current->width;
  619.    *height = Current->height;
  620.  
  621.    if (Current->rgb_flag) {
  622.       *mode = 1;
  623.       *depth = 8;
  624.    }
  625.    else {
  626.       *mode = 0;
  627.       *depth = Current->depth;
  628.    }
  629. }
  630.  
  631.  
  632.  
  633. GLenum dd_read_buffer( GLenum mode )
  634. {
  635.    /*return Current->readbuffer;*/
  636.    return mode;
  637. }
  638.  
  639.  
  640.  
  641. GLenum dd_draw_buffer( GLenum mode )
  642. {
  643.    /*return Current->drawbuffer;*/
  644.    return mode;
  645. }
  646.  
  647.  
  648.  
  649. /****************************************/
  650. /*       Simple Render Functions        */
  651. /****************************************/
  652.  
  653. /*
  654.  * Set current color index.
  655.  */
  656. void dd_index( GLuint index )
  657. {
  658.    Current->pixel = index;
  659.    SetAPen( Current->rp, (unsigned long) index );
  660. }
  661.  
  662.  
  663. /* Set the index mode bitplane mask. */
  664. void dd_index_mask( GLuint mask )
  665. {
  666.    Current->rp->Mask = (UBYTE) mask;
  667. }
  668.  
  669.  
  670. /*
  671.  * Set current RGBA color.
  672.  */
  673. void dd_color( const GLfloat color[4] )
  674. {
  675.    GLuint ir, ig, ib, ia;
  676.  
  677.    ir = (GLuint) (color[0] * 255.0);
  678.    ig = (GLuint) (color[1] * 255.0);
  679.    ib = (GLuint) (color[2] * 255.0);
  680.    ia = (GLuint) (color[3] * 255.0);
  681.  
  682.    Current->pixel = (ia << 24) | (ib << 16) | (ig << 8) | ir;
  683. }
  684.  
  685.  
  686. void dd_color_mask( GLboolean rmask, GLboolean gmask,
  687.             GLboolean bmask, GLboolean amask )
  688. {
  689.    /* TODO */
  690. }
  691.  
  692.  
  693.  
  694. /*
  695.  * Write a pixel of the current color.
  696.  */
  697. void dd_draw_pixel( GLint x, GLint y )
  698. {
  699.    y = Current->bottom - y;
  700.    x = Current->left + x;
  701.  
  702.    if (Current->rgb_flag) {
  703.       Current->rgb_buffer[ y * Current->width + x ] = Current->pixel;
  704.    }
  705.    else {
  706.       WritePixel( Current->rp, (long) x, (long) y );
  707.    }
  708. }
  709.  
  710.  
  711.  
  712. /*
  713.  * Draw a line segment using current color.
  714.  */
  715. void dd_draw_line( GLint x0, GLint y0, GLint x1, GLint y1 )
  716. {
  717.    x0 = Current->left + x0;
  718.    y0 = Current->bottom - y0;
  719.    x1 = Current->left + x1;
  720.    y1 = Current->bottom - y1;
  721.  
  722.    if (Current->rgb_flag) {
  723.       /* use bresenham's alg. to draw line using Current->pixel */
  724. #define BRESENHAM_PLOT( X, Y )        \
  725.         Current->rgb_buffer[Y*Current->width+X] = Current->pixel;
  726.       BRESENHAM( x0, y0, x1, y1 );
  727.    }
  728.    else {
  729.       Move( Current->rp, (long) x0, (long) y0 );
  730.       Draw( Current->rp, (long) x1, (long) y1 );
  731.    }
  732. }
  733.  
  734.  
  735.  
  736. /*
  737.  * Draw a filled polygon of a single color.  If there is hardware/OS support
  738.  * for polygon drawing use that here.  Otherwise, call a function in
  739.  * polygon.c to do the drawing.
  740.  */
  741. void dd_draw_polygon( GLuint n, GLint x[], GLint y[] )
  742. {
  743.    if (Current->rgb_flag) {
  744.       gl_polygon( n, x, y );
  745.    }
  746.    else {
  747.       GLuint i;
  748.       AreaMove( Current->rp, (long) (Current->left + x[0]),
  749.                  (long) (Current->bottom - y[0]) );
  750.       for (i=1;i<n;i++) {
  751.          AreaDraw( Current->rp, (long) (Current->left + x[i]),
  752.                 (long) (Current->bottom - y[i]) );
  753.       }
  754.       AreaEnd( Current->rp );
  755.    }
  756. }
  757.  
  758.  
  759.  
  760. /*
  761.  * Fill a rectangular window region with the current color.
  762.  * Input:  x, y - pixel coordinate of lower-left corner of rectagle
  763.  *         width, height - size of rectangle to fill.
  764.  */
  765. void dd_draw_rectangle( GLint x, GLint y, GLint width, GLint height )
  766. {
  767.    if (Current->rgb_flag) {
  768.       GLint i, j;
  769.       GLint y0, y1;
  770.       y0 = Current->bottom - y - height + 1;
  771.       y1 = Current->bottom - y;
  772.       for (j=y0;j<=y1;j++) {
  773.          register GLuint *p = Current->rgb_buffer + j * Current->width + x;
  774.          for (i=0;i<width;i++) {
  775.         *p++ = Current->pixel;
  776.          }
  777.       }
  778.    }
  779.    else {
  780.       UBYTE mask_save;
  781.       mask_save = Current->rp->Mask;
  782.       Current->rp->Mask = 0xff;
  783.       RectFill( Current->rp,
  784.             Current->left+x,         Current->bottom-y-height+1,
  785.             Current->left+x+width-1, Current->bottom-y );
  786.       Current->rp->Mask = mask_save;
  787.    }
  788. }
  789.  
  790.  
  791.  
  792. /****************************************/
  793. /*        Span Rendering Functions      */
  794. /****************************************/
  795.  
  796.  
  797. /* Write a horizontal span of color-index pixels with a boolean mask. */
  798. void dd_write_index_span( GLuint n, GLint x, GLint y,
  799.               const GLuint index[], const GLubyte mask[] )
  800. {
  801.    GLuint i;
  802.  
  803.    x = Current->left + x;
  804.    y = Current->bottom - y;
  805.  
  806.    for (i=0;i<n;i++,x++) {
  807.       if (mask[i]) {
  808.      SetAPen( Current->rp, (unsigned long) index[i] );
  809.      WritePixel( Current->rp, (long) x, (long) y );
  810.       }
  811.    }
  812. }
  813.  
  814.  
  815.  
  816. void dd_write_monoindex_span( GLuint n, GLint x, GLint y,
  817.                   GLuint index, const GLubyte mask[] )
  818. {
  819.    GLuint i;
  820.  
  821.    x = Current->left + x;
  822.    y = Current->bottom - y;
  823.  
  824.    SetAPen( Current->rp, (unsigned long) index );
  825.  
  826.    for (i=0;i<n;i++,x++) {
  827.       if (mask[i]) {
  828.      WritePixel( Current->rp, (long) x, (long) y );
  829.       }
  830.    }
  831. }
  832.  
  833.  
  834.  
  835. /* Read a horizontal span of color-index pixels. */
  836. void dd_read_index_span( GLuint n, GLint x, GLint y, GLuint index[] )
  837. {
  838.    GLuint i;
  839.  
  840.    x = Current->left + x;
  841.    y = Current->bottom - y;
  842.  
  843.    for (i=0;i<n;i++,x++) {
  844.       index[i] = (GLuint) ReadPixel( Current->rp, (long) x, (long) y );
  845.    }
  846. }
  847.  
  848.  
  849.  
  850. /*
  851.  * Write a span of RGBA pixels with a mask.
  852.  */
  853. void dd_write_color_span( GLuint n, GLint x, GLint y,
  854.               const GLubyte red[], const GLubyte green[],
  855.               const GLubyte blue[], const GLubyte alpha[],
  856.               const GLubyte mask[] )
  857. {
  858.    GLuint i, *ptr;
  859.  
  860.    x = Current->left + x;
  861.    y = Current->bottom - y;
  862.  
  863.    ptr = Current->rgb_buffer + y * Current->width + x;
  864.    for (i=0;i<n;i++) {
  865.       if (mask[i]) {
  866.          *ptr = (alpha[i] << 24) | (blue[i] << 16) | (green[i] << 8) | red[i];
  867.       }
  868.       ptr++;
  869.    }
  870. }
  871.  
  872.  
  873.  
  874. void dd_write_monocolor_span( GLuint n, GLint x, GLint y,
  875.                   GLubyte red, GLubyte green,
  876.                   GLubyte blue, GLubyte alpha,
  877.                   const GLubyte mask[] )
  878. {
  879.    GLuint i, *ptr, p;
  880.  
  881.    x = Current->left + x;
  882.    y = Current->bottom - y;
  883.  
  884.    p = (alpha << 24) | (blue << 16) | (green << 8) | red;
  885.  
  886.    ptr = Current->rgb_buffer + y * Current->width + x;
  887.    for (i=0;i<n;i++) {
  888.       if (mask[i]) {
  889.      *ptr = p;
  890.       }
  891.       ptr++;
  892.    }
  893. }
  894.  
  895.  
  896.  
  897. /* Read a horizontal span of color pixels. */
  898. void dd_read_color_span( GLuint n, GLint x, GLint y,
  899.              GLubyte red[], GLubyte green[],
  900.                  GLubyte blue[], GLubyte alpha[] )
  901. {
  902.    GLuint i, *ptr, p;
  903.    GLint d255 = 1.0 / 255.0;
  904.  
  905.    x = Current->left + x;
  906.    y = Current->bottom - y;
  907.  
  908.    ptr = Current->rgb_buffer + y * Current->width + x;
  909.    for (i=0;i<n;i++) {
  910.       p = *ptr++;
  911.       red[i]   =   p      & 0xff;
  912.       green[i] = ((p>>8)  & 0xff) << 8;
  913.       blue[i]  = ((p>>16) & 0xff) << 16;
  914.       alpha[i] = ((p>>24) & 0xff) << 24;
  915.    }
  916. }
  917.  
  918.